package com.zhiche.lisa.bms.service.statistics.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.zhiche.lisa.bms.dao.mapper.statistics.StaticOrderCompositeMapper;
import com.zhiche.lisa.bms.dao.model.statistics.*;
import com.zhiche.lisa.bms.dao.model.view.FeeBill;
import com.zhiche.lisa.bms.dao.model.view.FeeBillDetail;
import com.zhiche.lisa.bms.pojo.bo.statistics.BillDetailBO;
import com.zhiche.lisa.bms.pojo.bo.statistics.NovoIncomeCostBO;
import com.zhiche.lisa.bms.service.statistics.*;
import com.zhiche.lisa.bms.service.view.FeeBillDetailService;
import com.zhiche.lisa.bms.service.view.FeeBillService;
import com.zhiche.lisa.bms.utils.BmsCollectionUtils;
import com.zhiche.lisa.core.supports.BaseException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 订单统计综合表 服务实现类
 * </p>
 *
 * @author liangpeng
 * @since 2019-01-18
 */
@Service
public class StaticOrderCompositeServiceImpl extends ServiceImpl<StaticOrderCompositeMapper, StaticOrderComposite> implements StaticOrderCompositeService {

    private final Logger LOGGER = LoggerFactory.getLogger(StaticOrderCompositeServiceImpl.class);

    @Autowired
    private StaticOrderService staticOrderService;

    @Autowired
    private StaticBillService staticBillService;

    @Autowired
    private StaticBillDetailService staticBillDetailService;

    @Autowired
    private StaticIncomeCostService staticIncomeCostService;

    @Autowired
    private FeeBillDetailService feeBillDetailService;

    @Autowired
    private FeeBillService feeBillService;

    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    private String LEVELING_FEE_COST_TYPE = "调平费用";

    @Autowired
    private StaticNovoIncomeCostService staticNovoIncomeCostService;

    private String EST_PRICE_TYPE = "暂估";

    private String ACT_PRICE_TYPE = "正式";

    /**
     * 创建订单统计综合表
     */
    @Override
    public void insertOrderComposite() {

        int nThreads = 5;

        try {
            // 更新发生变化的账单
            LOGGER.info("updateBill start");
            updateBill(nThreads, 0);
            LOGGER.info("updateBill end");

            // 更新收入价格数据
            LOGGER.info("updateNovoIncomeCost start");
            updateNovoIncomeCost(nThreads, 0);
            LOGGER.info("updateNovoIncomeCost end");

            // 更新订单
            LOGGER.info("updateOrder start");
            updateOrder(nThreads, 0);
            LOGGER.info("updateOrder end");

            // 更新账单
            updateStaticBill(nThreads, 0);
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage());
            throw new BaseException(ex.getMessage());
        }
    }

    /**
     * 更新订单发生变化
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateOrder(int nThreads, int intCount) {
        //查询订单发生变化
        EntityWrapper<StaticOrder> ewStaticOrder = new EntityWrapper<>();
        ewStaticOrder.eq("deal_status", 0);
        ewStaticOrder.orderBy("gmt_modify");
        if (intCount > 0) {
            ewStaticOrder.last("limit " + intCount);
        }
        // ewStaticOrder.in("sys_order_id", getSysOrderIdList());
        List<StaticOrder> listOrder = staticOrderService.selectList(ewStaticOrder);
        if (CollectionUtils.isNotEmpty(listOrder)) {
            int size = listOrder.size();
            if (size <= 10) {
                nThreads = 1;
            }
            ExecutorService executorService1 = Executors.newFixedThreadPool(nThreads);
            int remaider = size % nThreads;  //(先计算出余数)
            int number = size / nThreads;  //然后是商
            int offset = 0;//偏移量

            try {
                for (int i = 0; i < nThreads; i++) {
                    // 先分组
                    if (remaider > 0) {
                        final List<StaticOrder> enrollList = listOrder.subList(i * number + offset, (i + 1) * number + offset + 1);
                        executorService1.execute(() -> {
                            // 检查是否共享线程
                            LOGGER.info("测试 -> {}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
                            this.updateOrder(enrollList);
                        });
                        remaider--;
                        offset++;
                    } else {
                        final List<StaticOrder> enrollList = listOrder.subList(i * number + offset, (i + 1) * number + offset);
                        executorService1.execute(() -> {
                            // 检查是否共享线程
                            LOGGER.info("测试 -> {}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
                            this.updateOrder(enrollList);
                        });
                    }
                }

                executorService1.shutdown();
                while (!executorService1.awaitTermination(60, TimeUnit.SECONDS)) {
                    LOGGER.info("线程池没有关闭");
                }
                LOGGER.info("线程池已经关闭");
            } catch (Exception ex) {
                LOGGER.error("updateOrder {}", ex);
                throw new BaseException(ex.getMessage());
            }
        }


    }

    //更新订单
    private void updateOrder(List<StaticOrder> orders) {
        Date date = new Date();
        try {
            if (CollectionUtils.isNotEmpty(orders)) {
                Set<String> sysOrderIdSet = Sets.newHashSet();
                orders.forEach(staticOrder -> {
                    if ("取消".equals(staticOrder.getOrderStatus()) || "暂运".equals(staticOrder.getOrderStatus())) {
                        staticOrder.setIsDelete(1);
                        // EntityWrapper<StaticOrderComposite> ewOrder = new EntityWrapper<>();
                        // ewOrder.eq("sys_order_id", staticOrder.getSysOrderId());
                        // this.delete(ewOrder);
                        sysOrderIdSet.add(staticOrder.getSysOrderId());
                    }
                    staticOrder.setDealStatus(1);
                    staticOrder.setDealTime(date);
                });
                if (CollectionUtils.isNotEmpty(sysOrderIdSet)) {
                    EntityWrapper<StaticOrderComposite> ewOrder = new EntityWrapper<>();
                    ewOrder.in("sys_order_id", sysOrderIdSet);
                    this.delete(ewOrder);
                }
                //更新原有订单状态
                if (CollectionUtils.isNotEmpty(orders)) {
                    staticOrderService.updateBatchById(orders);
                }
            }
        } catch (Exception ex) {
            LOGGER.error("updateOrder: {}", ex);
            throw new BaseException(ex.getMessage());
        }
    }


    /**
     * 更新发生变化的账单
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateBill(int nThreads, int intCount) {
        //查询账单发生变化
        List<BillDetailBO> listBillDetailBO = staticBillDetailService.getARBillDetailBO(intCount);
        Map<String, BigDecimal> billDtlInvoiceMoneyMap = staticBillDetailService.getBillDetailInvoiceMoney();

        if (CollectionUtils.isNotEmpty(listBillDetailBO)) {
            int size = listBillDetailBO.size();
            if (size <= 10) {
                nThreads = 1;
            }
            ExecutorService executorService1 = Executors.newFixedThreadPool(nThreads);
            int remaider = size % nThreads;  //(先计算出余数)
            int number = size / nThreads;  //然后是商
            int offset = 0;//偏移量

            try {
                for (int i = 0; i < nThreads; i++) {
                    // 先分组
                    if (remaider > 0) {
                        final List<BillDetailBO> enrollList = listBillDetailBO.subList(i * number + offset, (i + 1) * number + offset + 1);
                        executorService1.execute(() -> {
                            // 检查是否共享线程
                            LOGGER.info("线程 -> {}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
                            this.updateBill(enrollList, billDtlInvoiceMoneyMap);
                        });
                        remaider--;
                        offset++;
                    } else {
                        final List<BillDetailBO> enrollList = listBillDetailBO.subList(i * number + offset, (i + 1) * number + offset);
                        executorService1.execute(() -> {
                            // 检查是否共享线程
                            LOGGER.info("线程 -> {}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
                            this.updateBill(enrollList, billDtlInvoiceMoneyMap);
                        });
                    }
                }

                executorService1.shutdown();
                while (!executorService1.awaitTermination(60, TimeUnit.SECONDS)) {
                    LOGGER.info("线程池没有关闭");
                }
                LOGGER.info("线程池已经关闭");
            } catch (Exception ex) {
                LOGGER.error("updateBill: {}", ex);
                throw new BaseException(ex.getMessage());
            }
        }
    }

    /**
     * 更新账单数据
     *
     * @param listBillDetails
     */
    private void updateBill(List<BillDetailBO> listBillDetails, Map<String, BigDecimal> billDtlInvoiceMoneyMap) {

        Date date = new Date();
        // List<StaticBill> listBill = Lists.newArrayList();
        // List<StaticBillDetail> listBillDetail = Lists.newArrayList();

        Set<Long> billHeadIdSet = new HashSet<>();
        Set<Long> billDetailIdSet = new HashSet<>();
        // Map<String, BigDecimal> incomeBillChargeMap = Maps.newHashMap();

        try {
            listBillDetails.forEach(billDetailBO -> {

                // BigDecimal billCharge = Objects.nonNull(billDetailBO.getIncomeBillCharge()) ? billDetailBO.getIncomeBillCharge() : BigDecimal.ZERO;
                // 2019-05-20 更换字段
                BigDecimal billOtherFee = Objects.nonNull(billDetailBO.getBillOtherFee()) ? billDetailBO.getBillOtherFee() : BigDecimal.ZERO;
                // 申请开票金额
                // BigDecimal invoiceRequestMoney = Objects.nonNull(billDetailBO.getInvoiceRequestMoney()) ? billDetailBO.getInvoiceRequestMoney() : BigDecimal.ZERO;
                // 已开票金额
                // BigDecimal invoiceMoney = Objects.nonNull(billDetailBO.getInvoiceMoney()) ? billDetailBO.getInvoiceMoney() : BigDecimal.ZERO;
                BigDecimal mapValue = billDtlInvoiceMoneyMap.get(billDetailBO.getSysOrderId());
                BigDecimal invoiceMoney = Objects.nonNull(mapValue) ? mapValue : BigDecimal.ZERO;

                // EntityWrapper<StaticBillDetail> ewBillDetail = new EntityWrapper<>();
                // ewBillDetail.eq("bill_id", billDetailBO.getBillId());
                // int orderCount = staticBillDetailService.selectCount(ewBillDetail);

                // 2019-09-26 去除账单其他费用
                // BigDecimal everyBillCharge = incomeBillChargeMap.get(billDetailBO.getBillId());
                // if (Objects.isNull(everyBillCharge)) {
                //
                //     // 计算条数
                //     int orderCount = getBillDetailDistinctCount(billDetailBO.getBillId());
                //     //平均分配每个订单的账单的金额
                //     everyBillCharge = BigDecimal.ZERO;
                //     if (orderCount > 0) {
                //         // everyBillCharge = billCharge.divide(new BigDecimal(orderCount), 2, RoundingMode.HALF_UP);
                //         everyBillCharge = billOtherFee.divide(new BigDecimal(orderCount), 2, RoundingMode.HALF_UP);
                //     }
                //     incomeBillChargeMap.put(billDetailBO.getBillId(), everyBillCharge);
                // }

                // EntityWrapper<StaticOrderComposite> ewStaticOrderComposite = new EntityWrapper<>();
                // ewStaticOrderComposite.eq("sys_order_id", billDetailBO.getSysOrderId());
                //
                // StaticOrderComposite staticOrderComposite = this.selectOne(ewStaticOrderComposite);
                StaticOrderComposite staticOrderComposite = this.selectById(billDetailBO.getOrderCompositeId());
                if (Objects.nonNull(staticOrderComposite)) {
                    if (StringUtils.isNotBlank(billDetailBO.getBillId())) {
                        staticOrderComposite.setIncomeBillId(billDetailBO.getBillId());
                    }

                    if (StringUtils.isNotEmpty(billDetailBO.getBillStatus())) {
                        staticOrderComposite.setIncomeBillStatus(billDetailBO.getBillStatus());
                    }

                    if (StringUtils.isNotEmpty(billDetailBO.getIncomeInvoiceStatus())) {
                        staticOrderComposite.setIncomeInvoiceStatus(billDetailBO.getIncomeInvoiceStatus());
                    }

                    // if (StringUtils.isNotEmpty((billDetailBO.getIncomeInvoiceNo()))) {
                    //     staticOrderComposite.setIncomeInvoiceNo(billDetailBO.getIncomeInvoiceNo());
                    // }
                    // 2019-07-01 修改获取字段
                    if (StringUtils.isNotEmpty((billDetailBO.getInvoiceCode()))) {
                        staticOrderComposite.setIncomeInvoiceNo(billDetailBO.getInvoiceCode());
                    }

                    if (StringUtils.isNotEmpty(billDetailBO.getIncomeInvoiceDate())) {
                        staticOrderComposite.setIncomeInvoiceDate(billDetailBO.getIncomeInvoiceDate());
                    }

                    // if (StringUtils.isNotEmpty(billDetailBO.getUnitName())) {
                    //     staticOrderComposite.setUnitName(billDetailBO.getUnitName());
                    // }

                    if (StringUtils.isNotEmpty(billDetailBO.getReceiptDate())) {
                        staticOrderComposite.setReceiptDate(billDetailBO.getReceiptDate());
                    }

                    // if (Objects.nonNull(billDetailBO.getIncomeBillCharge())) {
                    //     staticOrderComposite.setIncomeBillCharge(billDetailBO.getIncomeBillCharge());
                    // }

                    if (Objects.nonNull(billDetailBO.getInvoiceRequestMoney())) {
                        // 2019-05-07 不均摊 申请开票金额
                        // if (Objects.nonNull(staticOrderComposite.getIncomeInvoiceApply())) {
                        //     staticOrderComposite.setIncomeInvoiceApply(staticOrderComposite.getIncomeInvoiceApply().add(invoiceRequestMoney));
                        // } else {
                        //     staticOrderComposite.setIncomeInvoiceApply(invoiceRequestMoney);
                        // }
                        staticOrderComposite.setIncomeInvoiceApply(billDetailBO.getInvoiceRequestMoney());
                    }

                    if (Objects.nonNull(invoiceMoney)) {
                        // invoiceMoney 已开票金额
                        // if (Objects.nonNull(staticOrderComposite.getIncomeInvoiceMoney())) {
                        //     staticOrderComposite.setIncomeInvoiceMoney(staticOrderComposite.getIncomeInvoiceMoney().add(invoiceMoney));
                        // } else {
                        //     staticOrderComposite.setIncomeInvoiceMoney(invoiceMoney);
                        // }
                        staticOrderComposite.setIncomeInvoiceMoney(invoiceMoney);
                    }

                    // 2019-09-26 去除账单其他费用
                    // if (Objects.nonNull(everyBillCharge)) {
                    //     // if (Objects.nonNull(staticOrderComposite.getIncomeBillOtherCost())) {
                    //     //     staticOrderComposite.setIncomeBillOtherCost(staticOrderComposite.getIncomeBillOtherCost().add(everyBillCharge));
                    //     // } else {
                    //     //     staticOrderComposite.setIncomeBillOtherCost(everyBillCharge);
                    //     // }
                    //     staticOrderComposite.setIncomeBillOtherCost(everyBillCharge);
                    // }

                    // 2019-07-31 新增调平费用
                    if (Objects.nonNull(billDetailBO.getLevelingFee())) {
                        this.createLevelingFeeCost(billDetailBO.getSysOrderId(), billDetailBO.getLevelingFee());
                    }

                    this.updateById(staticOrderComposite);
                }

                // EntityWrapper<StaticBill> ewStaticBill = new EntityWrapper<>();
                // ewStaticBill.eq("bill_id", billDetailBO.getBillId())
                //         .eq("deal_status", "0");
                // StaticBill staticBill = staticBillService.selectOne(ewStaticBill);
                // if (Objects.nonNull(staticBill)) {
                //     staticBill.setDealStatus(1);
                //     staticBill.setDealTime(date);
                //     listBill.add(staticBill);
                // }
                billHeadIdSet.add(billDetailBO.getId());

                // EntityWrapper<StaticBillDetail> ewStaticBillDetail = new EntityWrapper<>();
                // ewStaticBillDetail.eq("bill_id", billDetailBO.getBillId())
                //         .eq("deal_status", "0")
                //         .eq("sys_order_id", billDetailBO.getSysOrderId());
                // StaticBillDetail staticBillDetail = staticBillDetailService.selectOne(ewStaticBillDetail);
                // if (Objects.nonNull(staticBillDetail)) {
                //     staticBillDetail.setDealStatus(1);
                //     staticBillDetail.setDealTime(date);
                //     listBillDetail.add(staticBillDetail);
                // }

                billDetailIdSet.add(billDetailBO.getBillDetailId());
            });

            //更新原有账单状态
            // if (CollectionUtils.isNotEmpty(listBill)) {
            //     staticBillService.updateBatchById(listBill);
            // }

            if (CollectionUtils.isNotEmpty(billHeadIdSet)) {
                List<StaticBill> billList = Lists.newArrayList();
                billHeadIdSet.forEach(billHeadId -> {
                    StaticBill staticBill = new StaticBill();
                    staticBill.setId(billHeadId);
                    staticBill.setDealStatus(1);
                    staticBill.setDealTime(date);
                    billList.add(staticBill);
                });
                staticBillService.updateBatchById(billList);
            }

            // if (CollectionUtils.isNotEmpty(listBillDetail)) {
            //     staticBillDetailService.updateBatchById(listBillDetail);
            // }

            if (CollectionUtils.isNotEmpty(billDetailIdSet)) {
                List<StaticBillDetail> billDetailList = Lists.newArrayList();
                billDetailIdSet.forEach(billDetailId -> {
                    StaticBillDetail staticBillDetail = new StaticBillDetail();
                    staticBillDetail.setId(billDetailId);
                    staticBillDetail.setDealStatus(1);
                    staticBillDetail.setDealTime(date);
                    billDetailList.add(staticBillDetail);
                });
                staticBillDetailService.updateBatchById(billDetailList);
            }
        } catch (Exception ex) {
            LOGGER.error("updateBill: {}", ex);
            throw new BaseException(ex.getMessage());
        }

    }

    /**
     * 新增调平费用
     *
     * @param sysOrderId
     * @param levelingFee
     */
    private void createLevelingFeeCost(String sysOrderId, BigDecimal levelingFee) {
        EntityWrapper<StaticIncomeCost> ew = new EntityWrapper<>();
        ew.eq("sys_order_id", sysOrderId);
        ew.eq("cost_type", LEVELING_FEE_COST_TYPE);
        int levelingFeeCount = staticIncomeCostService.selectCount(ew);
        if (levelingFeeCount <= 0) {
            StaticIncomeCost staticIncomeCost = new StaticIncomeCost();
            staticIncomeCost.setDealStatus(0);
            staticIncomeCost.setCostType(LEVELING_FEE_COST_TYPE);
            staticIncomeCost.setPriceType("应收");
            staticIncomeCost.setSysOrderId(sysOrderId);
            staticIncomeCost.setMoney(levelingFee);
            staticIncomeCost.setGmtCreate(new Date());
            staticIncomeCostService.insert(staticIncomeCost);
        }
    }


    /**
     * 计算订单数量
     *
     * @param billId
     * @return
     */
    private int getBillDetailDistinctCount(String billId) {
        int count = 0;
        EntityWrapper<StaticBillDetail> ewBillDetail = new EntityWrapper<>();
        ewBillDetail.setSqlSelect("distinct sys_order_id");
        ewBillDetail.eq("bill_id", billId);
        List<Object> objectList = staticBillDetailService.selectObjs(ewBillDetail);
        if (CollectionUtils.isNotEmpty(objectList)) {
            return objectList.size();
        }
        return count;
    }

    // /**
    //  * 更新发生变化的价格
    //  */
    // @Transactional(rollbackFor = Exception.class)
    // @Override
    // public void updatePrice(int nThreads, int intCount) {
    //     //根据订单号和客户运单号
    //     List<StaticIncomeCost> distinctListIncomeCost = staticIncomeCostService.getDistinctOrderNoDeal(intCount);
    //     if (CollectionUtils.isNotEmpty(distinctListIncomeCost)) {
    //         ExecutorService executorService1 = Executors.newFixedThreadPool(nThreads);
    //         int size = distinctListIncomeCost.size();
    //         if (size <= 10) {
    //             nThreads = 1;
    //         }
    //         int remaider = size % nThreads;  //(先计算出余数)
    //         int number = size / nThreads;  //然后是商
    //         int offset = 0;//偏移量
    //         try {
    //             for (int i = 0; i < nThreads; i++) {
    //                 // 先分组
    //                 if (remaider > 0) {
    //                     final List<StaticIncomeCost> enrollList = distinctListIncomeCost.subList(i * number + offset, (i + 1) * number + offset + 1);
    //                     // this.updatePrice(enrollList);
    //                     executorService1.execute(() -> {
    //                         // 检查是否共享线程
    //                         LOGGER.info("测试 -> {}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
    //                         this.updatePrice(enrollList);
    //                     });
    //                     remaider--;
    //                     offset++;
    //                 } else {
    //                     final List<StaticIncomeCost> enrollList = distinctListIncomeCost.subList(i * number + offset, (i + 1) * number + offset);
    //                     // this.updatePrice(enrollList);
    //                     executorService1.execute(() -> {
    //                         // 检查是否共享线程
    //                         LOGGER.info("测试 -> {}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
    //                         this.updatePrice(enrollList);
    //                     });
    //                 }
    //             }
    //             executorService1.shutdown();
    //             while (!executorService1.awaitTermination(60, TimeUnit.SECONDS)) {
    //                 LOGGER.info("线程池没有关闭");
    //             }
    //             LOGGER.info("线程池已经关闭");
    //         } catch (Exception ex) {
    //             LOGGER.error("updatePrice: {}", ex);
    //             throw new BaseException(ex.getMessage());
    //         }
    //     }
    // }


    /**
     * 更新收入价格
     *
     * @param nThreads
     * @param intCount
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateNovoIncomeCost(int nThreads, int intCount) {
        // 未处理数据
        List<NovoIncomeCostBO> notDealIncomeCostList = staticNovoIncomeCostService.getDistinctOrderIncomeCostNoDeal(intCount);
        if (CollectionUtils.isNotEmpty(notDealIncomeCostList)) {
            ExecutorService executorService1 = Executors.newFixedThreadPool(nThreads);
            int size = notDealIncomeCostList.size();
            if (size <= 10) {
                nThreads = 1;
            }
            int remaider = size % nThreads;  //(先计算出余数)
            int number = size / nThreads;  //然后是商
            int offset = 0;//偏移量
            try {
                for (int i = 0; i < nThreads; i++) {
                    // 先分组
                    if (remaider > 0) {
                        List<NovoIncomeCostBO> novoIncomeCostList = notDealIncomeCostList.subList(i * number + offset, (i + 1) * number + offset + 1);
                        executorService1.execute(() -> {
                            LOGGER.info("处理收入数据 -> {}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
                            this.dealNovoIncomeCostData(novoIncomeCostList);
                        });
                        remaider--;
                        offset++;
                    } else {
                        List<NovoIncomeCostBO> novoIncomeCostList = notDealIncomeCostList.subList(i * number + offset, (i + 1) * number + offset);
                        executorService1.execute(() -> {
                            LOGGER.info("处理收入数据 -> {}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
                            this.dealNovoIncomeCostData(novoIncomeCostList);
                        });
                    }
                }
                executorService1.shutdown();
                while (!executorService1.awaitTermination(60, TimeUnit.SECONDS)) {
                    LOGGER.info("处理收入数据线程池没有关闭");
                }
                LOGGER.info("处理收入数据线程池已经关闭");
            } catch (Exception ex) {
                LOGGER.error("updateNovoIncomeCost error: {}", ex);
                throw new BaseException(ex.getMessage());
            }
        }
    }

    /**
     * 更新账单
     *
     * @param nThreads
     * @param intCount
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateStaticBill(int nThreads, int intCount) {
        // 查询待处理的账单
        List<StaticBill> staticBillList = getWaitDisposeData(intCount);
        staticBillList.forEach(staticBill -> {
            // 1-找到对应的明细
            EntityWrapper<StaticBillDetail> ew = new EntityWrapper<>();
            ew.eq("bill_id", staticBill.getBillId());
            List<StaticBillDetail> staticBillDetailList = staticBillDetailService.selectList(ew);
            if (CollectionUtils.isNotEmpty(staticBillDetailList)) {
                // 2-循环匹配对应的BMS账单明细
                List<String> billCodeList = Lists.newArrayList();
                staticBillDetailList.forEach(staticBillDetail -> {
                    EntityWrapper<FeeBillDetail> feeBillDetailEw = new EntityWrapper<>();
                    feeBillDetailEw.eq("waybill_dtl_id", staticBillDetail.getSysWaybillId());
                    List<FeeBillDetail> feeBillDetailList = feeBillDetailService.selectList(feeBillDetailEw);

                    if (CollectionUtils.isNotEmpty(feeBillDetailList)) {
                        FeeBillDetail feeBillDetail = feeBillDetailList.get(0);

                        EntityWrapper<FeeBill> feeBillEw = new EntityWrapper<>();
                        feeBillEw.eq("bill_code", feeBillDetail.getBillCode());
                        List<FeeBill> feeBillList = feeBillService.selectList(feeBillEw);

                        if (CollectionUtils.isNotEmpty(feeBillList)) {
                            FeeBill feeBill = feeBillList.get(0);
                            if (!billCodeList.contains(feeBill.getPayApplyCode())) {
                                billCodeList.add(feeBill.getPayApplyCode());
                                // 更新对应的字段信息
                                updateStaticBillInfo(staticBill, feeBill);
                            }
                        }
                    }
                });
            }
        });
    }

    /**
     * 查询待处理的账单
     *
     * @param intCount
     * @return
     */
    private List<StaticBill> getWaitDisposeData(int intCount) {
        EntityWrapper<StaticBill> billEw = new EntityWrapper<>();
        billEw.like("bill_id", "BP", SqlLike.LEFT);
        // billEw.isNull("pay_invoice_code");
        if (intCount > 0) {
            billEw.last("limit " + intCount);
        }
        return staticBillService.selectList(billEw);
    }

    /**
     * 处理更新的字段信息
     *
     * @param updateStaticBill
     * @param feeBill
     */
    private void updateStaticBillInfo(StaticBill updateStaticBill, FeeBill feeBill) {
        // 支付申请单号
        if (StringUtils.isNotBlank(feeBill.getPayApplyCode())) {
            if (StringUtils.isNotBlank(updateStaticBill.getPayInvoiceCode())
                    && !updateStaticBill.getPayInvoiceCode().contains(feeBill.getPayApplyCode())) {
                updateStaticBill.setPayInvoiceCode(updateStaticBill.getPayInvoiceCode() + "," + feeBill.getPayApplyCode());
                // 支付申请日期
                if (feeBill.getApplyDate() != null && StringUtils.isNotBlank(updateStaticBill.getPayDate())) {
                    updateStaticBill.setPayDate(updateStaticBill.getPayDate() + "," + new DateTime(feeBill.getApplyDate()).toString(DATE_FORMAT));
                }
                // 支付其他金额
                if (updateStaticBill.getPayBillCharge() != null) {
                    updateStaticBill.setPayBillCharge(updateStaticBill.getPayBillCharge().add(feeBill.getDeductSum() == null ? BigDecimal.ZERO : feeBill.getDeductSum()));
                }
                // 支付金额
                if (updateStaticBill.getPayMoney() != null) {
                    updateStaticBill.setPayMoney(updateStaticBill.getPayMoney().add(feeBill.getGrossAmt() == null ? BigDecimal.ZERO : feeBill.getGrossAmt()));
                }
            } else {
                updateStaticBill.setPayInvoiceCode(feeBill.getPayApplyCode());
                // 支付申请日期
                if (feeBill.getApplyDate() != null) {
                    updateStaticBill.setPayDate(new DateTime(feeBill.getApplyDate()).toString(DATE_FORMAT));
                }
                // 支付其他金额
                updateStaticBill.setPayBillCharge(feeBill.getDeductSum());
                // 支付金额
                updateStaticBill.setPayMoney(feeBill.getDeductSum());
            }
        }
        staticBillService.updateById(updateStaticBill);
    }

    // /**
    //  * 更新价格
    //  *
    //  * @param distinctListIncomeCost
    //  */
    // private void updatePrice(List<StaticIncomeCost> distinctListIncomeCost) {
    //     // List<StaticIncomeCost> listIncomeCost = Lists.newArrayList();
    //     Date date = new Date();
    //
    //     List<String> sysOrderIdList = Lists.newArrayList();
    //
    //     try {
    //         List<StaticOrderComposite> updateOrderCompositeList = Lists.newArrayList();
    //         distinctListIncomeCost.forEach(staticIncomeCost -> {
    //             // EntityWrapper<StaticOrderComposite> ewStaticOrderComposite = new EntityWrapper<>();
    //             // ewStaticOrderComposite.eq("sys_order_id", staticIncomeCost.getSysOrderId());
    //             // StaticOrderComposite staticOrderComposite = this.selectOne(ewStaticOrderComposite);
    //             // 暂时用成本id来替换这个
    //             StaticOrderComposite staticOrderComposite = this.selectById(staticIncomeCost.getId());
    //             if (Objects.nonNull(staticOrderComposite)) {
    //                 EntityWrapper<StaticIncomeCost> staticIncomeCostEntityWrapper = new EntityWrapper<>();
    //                 // staticIncomeCostEntityWrapper.eq("sys_order_id", staticIncomeCost.getSysOrderId())
    //                 //         .eq("cost_type", "运输费");
    //                 staticIncomeCostEntityWrapper.eq("sys_order_id", staticIncomeCost.getSysOrderId());
    //                 List<StaticIncomeCost> lists = staticIncomeCostService.selectList(staticIncomeCostEntityWrapper);
    //
    //
    //                 //正式价格
    //                 int dealTimeSize = 0;
    //                 int normalDataSize = 0;
    //                 for (StaticIncomeCost incomeCost : lists) {
    //                     if ("应收".equals(incomeCost.getPriceType()) && "运输费".equals(incomeCost.getCostType())) {
    //                         normalDataSize++;
    //                         if (Objects.nonNull(incomeCost.getBmsDealTime())) {
    //                             dealTimeSize++;
    //                         }
    //                     }
    //                 }
    //                 Optional<StaticIncomeCost> cost1 = null;
    //                 if (dealTimeSize != 0 && dealTimeSize == normalDataSize) {
    //                     cost1 = lists.stream()
    //                             .filter(cost -> "应收".equals(cost.getPriceType()) && "运输费".equals(cost.getCostType()))
    //                             .max(Comparator.comparing(StaticIncomeCost::getBmsDealTime));
    //                 } else {
    //                     cost1 = lists.stream()
    //                             .filter(cost -> "应收".equals(cost.getPriceType()) && "运输费".equals(cost.getCostType()))
    //                             .max(Comparator.comparing(StaticIncomeCost::getGmtModify));
    //                 }
    //                 // Optional<StaticIncomeCost> cost1 = lists.stream()
    //                 //         .filter(cost -> "应收".equals(cost.getPriceType()) && "运输费".equals(cost.getCostType()))
    //                 //         .max(Comparator.comparing(StaticIncomeCost::getGmtModify));
    //                 if (cost1.isPresent()) {
    //                     staticOrderComposite.setOrderPrice(cost1.get().getPrice());
    //                     staticOrderComposite.setOrderMiles(cost1.get().getMiles());
    //                     staticOrderComposite.setOrderMoney(cost1.get().getMoney());
    //                     // if (Objects.nonNull(staticOrderComposite.getOrderMoney())) {
    //                     //     // 2019-05-20个人修改, 未确定. 当有运输费时, 但是没有公里数和运输费时候
    //                     //     if (Objects.isNull(staticOrderComposite.getOrderPrice()) && Objects.isNull(staticOrderComposite.getOrderMiles())) {
    //                     //         staticOrderComposite.setOrderPrice(staticOrderComposite.getOrderMoney());
    //                     //         staticOrderComposite.setOrderMiles(BigDecimal.ONE);
    //                     //     }
    //                     // }
    //
    //                     staticOrderComposite.setIsEstMiles("否");
    //                     staticOrderComposite.setIsEstPrice("否");
    //                     // 合同编码
    //                     staticOrderComposite.setContractId(cost1.get().getContractId());
    //                     // 规则id
    //                     staticOrderComposite.setRuleId(cost1.get().getRuleId());
    //                     // 开票单位
    //                     staticOrderComposite.setUnitName(cost1.get().getPartyaName());
    //                 }
    //
    //                 //暂估价
    //                 int estDealTimeSize = 0;
    //                 int estNormalDataSize = 0;
    //                 for (StaticIncomeCost incomeCost : lists) {
    //                     if (StringUtils.isNotBlank(incomeCost.getPriceType()) && incomeCost.getPriceType().contains("暂估") && "运输费".equals(incomeCost.getCostType())) {
    //                         estNormalDataSize++;
    //                         if (Objects.nonNull(incomeCost.getBmsDealTime())) {
    //                             estDealTimeSize++;
    //                         }
    //                     }
    //                 }
    //                 Optional<StaticIncomeCost> cost2 = null;
    //                 if (estDealTimeSize != 0 && estDealTimeSize == estNormalDataSize) {
    //                     cost2 = lists.stream()
    //                             .filter(cost -> StringUtils.isNotBlank(cost.getPriceType()) && cost.getPriceType().contains("暂估") && "运输费".equals(cost.getCostType()))
    //                             .max(Comparator.comparing(StaticIncomeCost::getBmsDealTime));
    //                 } else {
    //                     cost2 = lists.stream()
    //                             .filter(cost -> StringUtils.isNotBlank(cost.getPriceType()) && cost.getPriceType().contains("暂估") && "运输费".equals(cost.getCostType()))
    //                             .max(Comparator.comparing(StaticIncomeCost::getGmtModify));
    //                 }
    //                 // Optional<StaticIncomeCost> cost2 = lists.stream()
    //                 //         .filter(cost -> StringUtils.isNotBlank(cost.getPriceType()) && cost.getPriceType().contains("暂估") && "运输费".equals(cost.getCostType()))
    //                 //         .max(Comparator.comparing(StaticIncomeCost::getGmtModify));
    //                 if (cost2.isPresent()) {
    //                     if (Objects.isNull(staticOrderComposite.getOrderPrice()) || staticOrderComposite.getOrderPrice().compareTo(BigDecimal.ZERO) == 0) {
    //                         staticOrderComposite.setIsEstPrice("是");
    //                     }
    //                     staticOrderComposite.setOrderEstPrice(cost2.get().getPrice());
    //
    //                     if (Objects.isNull(staticOrderComposite.getOrderMiles()) || staticOrderComposite.getOrderMiles().compareTo(BigDecimal.ZERO) == 0) {
    //                         staticOrderComposite.setIsEstMiles("是");
    //                     }
    //                     staticOrderComposite.setOrderEstMiles(cost2.get().getMiles());
    //
    //                     if ("是".equals(staticOrderComposite.getIsEstMiles()) &&
    //                             "是".equals(staticOrderComposite.getIsEstPrice())) {
    //                         staticOrderComposite.setOrderMoney(cost2.get().getMoney());
    //                     }
    //                     // 合同编码
    //                     staticOrderComposite.setContractId(cost2.get().getContractId());
    //                     // 规则id
    //                     staticOrderComposite.setRuleId(cost2.get().getRuleId());
    //                 }
    //
    //                 //如果仍然为空，则初始化为0
    //                 if ((Objects.isNull(staticOrderComposite.getOrderMoney()))) {
    //                     staticOrderComposite.setOrderMoney(BigDecimal.ZERO);
    //                 }
    //
    //                 //每种其他费用取一个最大值的和
    //                 // String costType = "运输费";
    //                 // List<StaticIncomeCost> cost3 = staticIncomeCostService.getIncomeOtherCostByCostType(costType, staticOrderComposite.getSysOrderId());
    //
    //                 // 2019-05-21 修改, 当某种费用类型在一个价格类型中需要加入计算(洗车费在暂估有, 在应收没有, 这个时候需要加入到其他费用中)
    //                 // 2019-07-31 调平费用
    //                 List<StaticIncomeCost> otherCostList = getOtherCost(lists);
    //                 // List<StaticIncomeCost> cost3 = Lists.newArrayList();
    //                 // lists.stream()
    //                 //         .filter(cost -> !"运输费".equals(cost.getCostType()) && "应收".equals(cost.getPriceType()))
    //                 //         .forEach(cost -> {
    //                 //             cost3.add(cost);
    //                 //         });
    //                 // if (CollectionUtils.isEmpty(cost3)) {
    //                 //     lists.stream()
    //                 //             .filter(cost -> !"运输费".equals(cost.getCostType()) && StringUtils.isNotBlank(cost.getPriceType()) && cost.getPriceType().contains("暂估"))
    //                 //             .forEach(cost -> {
    //                 //                 cost3.add(cost);
    //                 //             });
    //                 // }
    //
    //                 BigDecimal otherCost = otherCostList.stream().map(StaticIncomeCost::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
    //                 staticOrderComposite.setOrderOtherCost(otherCost);
    //
    //                 BigDecimal incomeAmount;
    //                 if (Objects.nonNull(staticOrderComposite.getIncomeBillOtherCost())) {
    //                     incomeAmount = staticOrderComposite.getOrderMoney().add(staticOrderComposite.getOrderOtherCost()).add(staticOrderComposite.getIncomeBillOtherCost());
    //                 } else {
    //                     incomeAmount = staticOrderComposite.getOrderMoney().add(staticOrderComposite.getOrderOtherCost());
    //                 }
    //
    //                 staticOrderComposite.setOrderIncomeAmount(Objects.nonNull(incomeAmount) ? incomeAmount : BigDecimal.ZERO);
    //
    //                 updateOrderCompositeList.add(staticOrderComposite);
    //                 // this.updateById(staticOrderComposite);
    //
    //                 // EntityWrapper<StaticIncomeCost> ewCost = new EntityWrapper<>();
    //                 // ewCost.eq("sys_order_id", staticOrderComposite.getSysOrderId())
    //                 //         .eq("deal_status", "0");
    //                 // List<StaticIncomeCost> listCosts = staticIncomeCostService.selectList(ewCost);
    //                 // listIncomeCost.addAll(listCosts);
    //                 sysOrderIdList.add(staticOrderComposite.getSysOrderId());
    //             }
    //         });
    //
    //         if (CollectionUtils.isNotEmpty(updateOrderCompositeList)) {
    //             this.updateBatchById(updateOrderCompositeList);
    //         }
    //
    //         //更新原有价格状态
    //         // listIncomeCost.forEach(staticIncomeCost -> {
    //         //     staticIncomeCost.setDealStatus(1);
    //         //     staticIncomeCost.setDealTime(date);
    //         // });
    //         //
    //         // if (CollectionUtils.isNotEmpty(listIncomeCost)) {
    //         //     staticIncomeCostService.updateBatchById(listIncomeCost);
    //         // }
    //         if (CollectionUtils.isNotEmpty(sysOrderIdList)) {
    //             EntityWrapper<StaticIncomeCost> incomeCostEw = new EntityWrapper<>();
    //             incomeCostEw.in("sys_order_id", sysOrderIdList);
    //             incomeCostEw.eq("deal_status", 0);
    //             StaticIncomeCost updateIncomeCost = new StaticIncomeCost();
    //             updateIncomeCost.setDealStatus(1);
    //             updateIncomeCost.setDealTime(date);
    //             staticIncomeCostService.update(updateIncomeCost, incomeCostEw);
    //         }
    //
    //     } catch (Exception ex) {
    //         LOGGER.error("updatePrice {}", ex);
    //         throw new BaseException(ex.getMessage());
    //     }
    // }

    /**
     * 处理收入数据和更新价格
     *
     * @param novoIncomeCostList
     */
    private void dealNovoIncomeCostData(List<NovoIncomeCostBO> novoIncomeCostList) {
        Date date = new Date();

        try {
            List<StaticOrderComposite> updateOrderList = Lists.newArrayList();
            List<StaticNovoIncomeCost> updateIncomeCostList = Lists.newArrayList();

            novoIncomeCostList.forEach(staticNovoIncomeCostBo -> {
                StaticOrderComposite staticOrderComposite = this.selectById(staticNovoIncomeCostBo.getSysOrderCompositeId());
                if (Objects.nonNull(staticOrderComposite)) {
                    // 正式价格
                    if (ACT_PRICE_TYPE.equals(staticNovoIncomeCostBo.getPriceType())) {
                        // 正式价格
                        staticOrderComposite.setIsEstMiles("否");
                        staticOrderComposite.setIsEstPrice("否");
                    } else if (EST_PRICE_TYPE.equals(staticNovoIncomeCostBo.getPriceType())) {
                        // 暂估价格
                        staticOrderComposite.setIsEstMiles("是");
                        staticOrderComposite.setIsEstPrice("是");
                    }
                    // 开票单位
                    staticOrderComposite.setUnitName(staticNovoIncomeCostBo.getPartyaName());
                    // 单价
                    staticOrderComposite.setOrderPrice(staticNovoIncomeCostBo.getPrice());
                    // 公里数
                    staticOrderComposite.setOrderMiles(staticNovoIncomeCostBo.getMiles());
                    // 运输费
                    staticOrderComposite.setOrderMoney(staticNovoIncomeCostBo.getFare());
                    // 其他费用
                    staticOrderComposite.setOrderOtherCost(staticNovoIncomeCostBo.getOtherFee());
                    // 总金额
                    staticOrderComposite.setOrderIncomeAmount(staticNovoIncomeCostBo.getMoney());

                    updateOrderList.add(staticOrderComposite);
                }

                // 设置处理状态
                StaticNovoIncomeCost updateIncomeCost = new StaticNovoIncomeCost();
                updateIncomeCost.setId(staticNovoIncomeCostBo.getId());
                updateIncomeCost.setDealTime(date);
                updateIncomeCost.setDealStatus(1);
                updateIncomeCostList.add(updateIncomeCost);
            });

            if (CollectionUtils.isNotEmpty(updateOrderList)) {
                List<List<StaticOrderComposite>> subList = BmsCollectionUtils.subListByNum(updateOrderList, 1000);
                subList.forEach(list -> {
                    this.updateBatchById(list);
                });
            }

            if (CollectionUtils.isNotEmpty(updateIncomeCostList)) {
                List<List<StaticNovoIncomeCost>> subList = BmsCollectionUtils.subListByNum(updateIncomeCostList, 1000);
                subList.forEach(list -> {
                    staticNovoIncomeCostService.updateBatchById(list);
                });
            }
        } catch (Exception e) {
            LOGGER.error("dealNovoIncomeCostData {}", e);
            throw new BaseException(e.getMessage());
        }

    }

    /**
     * 计算其他费用
     *
     * @param allCost
     * @return
     */
    private List<StaticIncomeCost> getOtherCost(List<StaticIncomeCost> allCost) {
        List<StaticIncomeCost> otherCostList = Lists.newArrayList();
        List<StaticIncomeCost> standardOtherCostList = Lists.newArrayList();
        List<String> costTypeList = Lists.newArrayList();

        allCost.stream()
                .filter(cost -> !"运输费".equals(cost.getCostType()) && "应收".equals(cost.getPriceType()))
                .forEach(cost -> {
                    if (!StringUtils.isEmpty(cost.getCostType())) {
                        costTypeList.add(cost.getCostType());
                    }
                    otherCostList.add(cost);
                });
        allCost.stream()
                .filter(cost -> !"运输费".equals(cost.getCostType()) && StringUtils.isNotBlank(cost.getPriceType()) && cost.getPriceType().contains("暂估"))
                .forEach(cost -> {
                    standardOtherCostList.add(cost);
                });
        if (CollectionUtils.isEmpty(otherCostList)) {
            otherCostList.addAll(standardOtherCostList);
        } else {
            standardOtherCostList.forEach(staCost -> {
                if (!costTypeList.contains(staCost.getCostType())) {
                    otherCostList.add(staCost);
                }
            });
        }
        return otherCostList;
    }


    // private List<String> getSysOrderIdList() {
    //     List<String> sysOrderIdList = Lists.newArrayList();
    //     sysOrderIdList.add("ZC2019022801999");
    //     return sysOrderIdList;
    // }
}
